from PyQt4.QtGui import QGraphicsObject,QPen,QBrush,QColor,QFont,QGraphicsItem
from PyQt4 import QtCore,QtGui,Qt
from PyQt4.QtCore import QPointF,QSizeF,QObject,QRectF,QRect
from KCharts.KGraphics.KGraphicsSceneSubViewModel import KGraphicsSceneSubViewModel
from KApp import KConstants as vm

class KBaseDisplayItemModel(QtCore.QObject):
	def __init__(self,parent=None):
		QtCore.QObject.__init__(self,parent)
		self.m_stock=None
		
	def SetStockObject(self,stockobj):
		self.m_stock=stockobj
		
	def calculate(self):	
		pass
	
	def GetLogicRange(self):
		return None



class KBaseDisplayItem(QGraphicsItem):
	def __init__(self,viewmodel,stockobj):
		QGraphicsItem.__init__(self)
		assert(isinstance(viewmodel,KGraphicsSceneSubViewModel)==True)
		self.viewmodel=viewmodel # KGraphicsSceneSubViewModel
		self.model=None # KBaseDisplayItemModel
		self.m_stock=stockobj
		self.setPos(0,0) # parent of items inherited from this class will always placed at the (0,0) of the scene
		# pen for grid and border


	def SetModel(self,model):
		# set the item model used to perform calcuation
		self.model=model
		self.model.SetStockObject(self.m_stock)
		
	def GetModel(self):
		return self.model	
	
	def GetViewModel(self):
		return self.viewmodel
		
		#self.PrepareRenderPicture()
	def GetPen(self, purpose):
		if purpose=='gridPen':
			if not hasattr(self,'gridPen'):
				mpen=QPen(QColor(255,255,255))
				mpen.setStyle(QtCore.Qt.DotLine)
				mpen.setWidthF(0.5)	
				self.gridPen=mpen
			return self.gridPen
		elif purpose=='borderPen':
			if not hasattr(self,'borderPen'):
				mpen=QPen(QColor(255,0,0))
				mpen.setStyle(QtCore.Qt.DotLine)
				mpen.setWidthF(0.5)	
				self.borderPen=mpen
			return self.borderPen
		elif purpose=='mousePen':
			if not hasattr(self,'mousePen'):
				mpen=QPen(QtCore.Qt.white)
				mpen.setStyle(QtCore.Qt.DashDotLine)
				mpen.setWidthF(1)	
				self.mousePen=mpen
			return self.mousePen			
	def GetFont(self,purpose):
		if not hasattr(self,'labelText'):
			mfont= QFont("Times", 10)
			self.labelText=mfont
		return self.labelText	
	
	def OnMouseMove(self,pos):
		pass
	
	def PaintXAxis(self,painter,RectType,labenum):		

		mrect=self.viewmodel.GetViewScreenRect(RectType).toRect()
		gridspace=int(mrect.width()/labenum)
		if labenum==0:
			return False
		painter.setPen(self.GetPen('gridPen'))
		TimeList=self.m_stock.CurWindowData('Time')
		XCordinates=self.m_stock.CurWindowData('Index')	
		gridspace=int(mrect.width()/labenum)
		if gridspace==0:	
			return False
		# find the label to render
		indexlist,[]=self.viewmodel.mapScreenCordToLogic(vm.RectType.ContentBound,range(mrect.left(),mrect.right(),gridspace))
		labelstr=[]			
		for each_x in indexlist:
			if each_x in XCordinates:
				logicX=XCordinates.index(each_x)
				labelstr.append(TimeList[logicX])
			else:
				labelstr.append("")
		# call draw axis on base class
		return self.__InternalPaintXAxis(painter,RectType,labenum,labelstr)	
	
	def __InternalPaintXAxis(self,painter,RectType,labenum,labelstr):		
		painter.setPen(self.GetPen('gridPen'))
		painter.setFont(self.GetFont('labelText'))
		mrect=self.viewmodel.GetViewScreenRect(RectType).toRect()	
		if labenum==0:
			return False		
		gridspace=int(mrect.width()/labenum)
		if gridspace==0:
			return False
		ytop=mrect.top()
		ybottom=mrect.top()+0.2*(mrect.height())
		ytext=mrect.top()+0.5*(mrect.height())
		xtextoffset=20
		painter.drawLine(QtCore.QPointF(mrect.left(), ytop), QtCore.QPointF(mrect.right(), ytop))
		XCords=range(mrect.left(),mrect.right(),gridspace)
		for index in range(0,len(XCords)):
			each_x=XCords[index]
			each_text=labelstr[index]
			painter.drawLine(QtCore.QPointF(each_x, ytop), QtCore.QPointF(each_x, ybottom))
			painter.drawText(QtCore.QPointF(each_x-xtextoffset, ytext),str(each_text))
		return True
	
	def PaintYAxis(self,painter,RectType,labenum):		

		mrect=self.viewmodel.GetViewScreenRect(RectType).toRect()
		gridspace=int(mrect.height()/labenum)
		if labenum==0:
			return False
		painter.setPen(self.GetPen('gridPen'))
		gridspace=int(mrect.height()/labenum)
		if gridspace==0:	
			return False
		# find the label to render
		temp,pricelist=self.viewmodel.mapScreenCordToLogic(vm.RectType.ContentBound,[],range(mrect.top(),mrect.bottom(),gridspace))
		pricelist=[ "%.2f" %(x) for x in pricelist]
		# call draw axis on base class
		return self.__InternalPaintYAxis(painter,RectType,labenum,pricelist)	
	
	def __InternalPaintYAxis(self,painter,RectType,labenum,labelstr):
		
		painter.setPen(self.GetPen('gridPen'))
		painter.setFont(self.GetFont('labelText'))
		mrect=self.viewmodel.GetViewScreenRect(RectType).toRect()
		if labenum==0:
			return False		
		gridspace=int(mrect.height()/labenum)
		if gridspace==0:
			return False		
		xleft=mrect.left()
		xright=mrect.left()++0.1*(mrect.width())
		xtext=mrect.left()++0.2*(mrect.width())
		yoffset=5
		painter.drawLine(QtCore.QPointF(xleft, mrect.top()), QtCore.QPointF(xleft, mrect.bottom()))
		YCords=range(mrect.top(),mrect.bottom(),gridspace)
		for index in range(0,len(YCords)):
			each_y=YCords[index]
			each_text=labelstr[index]
			painter.drawLine(QtCore.QPointF(xleft, each_y), QtCore.QPointF(xright, each_y))
			painter.drawText(QtCore.QPointF(xtext, each_y+yoffset),str(each_text))
		return True
	
	def PaintGrid(self,painter,RectType,gridnum):


		painter.setPen(self.GetPen('gridPen'))
		mrect=self.viewmodel.GetViewScreenRect(RectType)
		mrect=mrect.toRect()
		if gridnum[0]>0:
			gridspace=int(mrect.width()/gridnum[0])
			if gridspace>0:
				for each_x in range(mrect.left(),mrect.right(),gridspace):
					painter.drawLine(QtCore.QPointF(each_x, mrect.top()), QtCore.QPointF(each_x, mrect.bottom()))
		if gridnum[1]>0:
			gridspace=int(mrect.height()/gridnum[1])
			if gridspace>0:
				for eacy_y in range(mrect.top(),mrect.bottom(),gridspace):
					painter.drawLine(QtCore.QPointF(mrect.left(), eacy_y), QtCore.QPointF(mrect.right(), eacy_y))		
			
	def PaintBorders(self,painter,RectType):
		# paint borders if necessary
		mrect=self.viewmodel.GetViewRect(RectType)
		painter.setPen(self.GetPen('borderPen'))
		painter.drawRect(mrect)


	def paint(self, p, *args):
		
		self.PrepareRenderPicture()
		p.drawPicture(0, 0, self.picture)



	def boundingRect(self):
		#print("bounding rect %s" %(self.picture.boundingRect()))
		#tesrect=self.viewmodel.GetViewRect('Outer')
		#actualrect=QtCore.QRectF(self.picture.boundingRect())
		#return actualrect
		if not hasattr(self,'picture'):
			self.PrepareRenderPicture() # if try to obtain rect before picture rendered, render it first
		return QtCore.QRectF(self.picture.boundingRect())
	